package com.tina.service.impl;

import com.baomidou.mybatisplus.core.conditions.AbstractWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tina.entity.TiMenu;
import com.tina.entity.TiUsers;
import com.tina.entity.vo.TiMenuLeftVo;
import com.tina.entity.vo.TiMenuVo;
import com.tina.mapper.TiMenuMapper;
import com.tina.mapper.TiRoleMapper;
import com.tina.mapper.TiRoleMenuRefMapper;
import com.tina.service.TiMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tina.util.TimeUtitl;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 菜单权限表 服务实现类
 * </p>
 *
 * @author PIGS
 * @since 2020-06-05
 */
@Service
@Transactional
public class TiMenuServiceImpl extends ServiceImpl<TiMenuMapper, TiMenu> implements TiMenuService {
    @Autowired
    private TiMenuMapper tiMenuMapper;

    @Autowired
    private TiRoleMapper tiRoleMapper;

    private Logger logger = LoggerFactory.getLogger(TiMenuServiceImpl.class);

    @Autowired
    private TiRoleMenuRefMapper tiRoleMenuRefMapper;

    /**
     * 条件查询菜单并分页
     *
     * @param tiMenu
     * @return
     */
    @Override
    public List<TiMenu> queryMenuList(TiMenu tiMenu) {
        AbstractWrapper<TiMenu, String, QueryWrapper<TiMenu>> wrapper = new QueryWrapper<TiMenu>();
        if (tiMenu != null) {
            if (!StringUtils.isEmpty(tiMenu.getMenuName())) {
                wrapper.like("menu_name", tiMenu.getMenuName());
            }
            if (tiMenu.getMenuId() != null) {
                wrapper.eq("menu_id", tiMenu.getMenuId());
            }
        }
        wrapper.orderByAsc("order_num");
        List<TiMenu> tiMenuList = tiMenuMapper.selectList(wrapper);
        List<TiMenu> collect = tiMenuList.stream().filter(TiMenu -> TiMenu.getState() != 2).collect(Collectors.toList());

        return collect;
    }

    /**
     * 级联查询父菜单
     *
     * @return
     */
    @Override
    public List<TiMenuVo> getAllMenus() {
        List<TiMenuVo> tiMenuMapperAllMenus = tiMenuMapper.getAllMenus();
        return tiMenuMapperAllMenus;
    }

    /**
     * respList 装最后返回的结果
     *
     * @param roleId
     * @return
     */
    @Override
    public List<TiMenuLeftVo> queryMenuLeftTreeByRoleId(Integer roleId) {

        List<TiMenuLeftVo> tiMenuLeftVos = tiMenuMapper.queryMenuLeftTreeByRoleId(roleId);
        List<TiMenuLeftVo> respList = new ArrayList<>();

        // 先找到所有的一级菜单
        for (TiMenuLeftVo value : tiMenuLeftVos) {
            //一级菜单parentId=0；
            if (value.getParentId() == 0) {
                respList.add(value);
            }
        }

        // 遍历一级菜单，开始找子菜单
        for (TiMenuLeftVo menu : respList) {
            List<TiMenuLeftVo> childlist = getChild(menu.getMenuId(), tiMenuLeftVos);
            menu.setChildren(childlist);
        }

        return respList;
    }

    /**
     * 递归查找子菜单
     * id 当前菜单id
     * menuList  所有的菜单
     */
    private List<TiMenuLeftVo> getChild(int id, List<TiMenuLeftVo> menuList) {
        // 找二级子菜单
        List<TiMenuLeftVo> childList = new ArrayList<>();
        for (TiMenuLeftVo menu : menuList) {
            // 遍历所有菜单，将父菜单id与传过来的id比较，如果相等就是该父菜单下的子菜单
            if (menu.getParentId() == id) {
                childList.add(menu);
            }
        }
        // 把子菜单的子菜单再循查找子菜单
        for (TiMenuLeftVo menu : childList) {
            List<TiMenuLeftVo> obj = getChild(menu.getMenuId(), menuList);
            menu.setChildren(obj);
        }
        return childList;
    }

    /**
     * 编辑菜单
     * <p>
     * 查询数据库中的菜单id名称是否一致
     * 如果跟id一致的名称就可以修改
     * 如果不与id不一致名字一致则断定为菜单名称已经存在
     *
     * @param tiMenu
     * @param select
     * @return
     */
    @Override
    public Integer editMenu(TiMenu tiMenu, Long select) {
        /**
         * 从mysql中查询数据如果用户名不存在则修改
         * 如果存在并且不与通过id查询的数据相同就返回101
         * 如果当前的用户名与使用id查询的数据用户名相同则修改
         */
        TiMenu selectById = tiMenuMapper.selectById(tiMenu.getMenuId());
        AbstractWrapper wrapper = new QueryWrapper<TiMenu>();
        wrapper.eq("menu_name", tiMenu.getMenuName());
        TiMenu selectOne = tiMenuMapper.selectOne(wrapper);
        if (selectById != null) {
            if (!selectById.getMenuName().equals(tiMenu.getMenuName())) {
                if (selectOne != null) {
                    return 101;
                }

            }
        }

        Subject subject = SecurityUtils.getSubject();
        TiUsers tiUsersSubject = (TiUsers) subject.getPrincipal();
        tiMenu.setUpdateBy(tiUsersSubject.getUserName());
        tiMenu.setParentId(select);
        int updateById = tiMenuMapper.updateById(tiMenu);
        if (updateById > 0) {
            return 200;
        }
        return 100;
    }

    /**
     * 添加菜单
     *
     * @param tiMenu
     * @return
     */
    @Override
    public Integer saveMenu(TiMenu tiMenu, Long select) {
        if (tiMenu != null) {
            if (!StringUtils.isEmpty(tiMenu.getMenuName())) {
                AbstractWrapper wrapper = new QueryWrapper();
                wrapper.eq("menu_name", tiMenu.getMenuName());
                TiMenu selectOne = tiMenuMapper.selectOne(wrapper);
                logger.info("selectOne={}", selectOne);
                if (selectOne != null) {
                    return 101;
                }

                Subject subject = SecurityUtils.getSubject();
                TiUsers tiUsersSubject = (TiUsers) subject.getPrincipal();
                if (tiUsersSubject != null) {
                    tiMenu.setUpdateBy(tiUsersSubject.getUserName());
                    tiMenu.setCreateBy(tiUsersSubject.getUserName());
                    tiMenu.setCreateTime(TimeUtitl.dateTime());
                    tiMenu.setParentId(select);
                    Integer saveMenuNum = tiMenuMapper.insert(tiMenu);
                    logger.info("saveMenuNum={}", saveMenuNum);
                    return 200;
                }
            }
        }
        return 100;
    }

    /**
     * 删除 菜单 把菜单的状态设置为 2
     * 0 显示
     * 1 隐藏
     * 2 删除
     * 判断 是否是父菜单
     * 主有是子菜单才能设置状态为 2
     *
     * @param menuId
     * @return 101 存在子菜单,不允许删除
     * 102 菜单已分配,不允许删除
     * 100 删除失败
     * 200 删除成功
     */
    @Override
    public Integer delMenu(Long menuId) {
        if (tiMenuMapper.queryCountMenuByParentId(menuId) > 0) {
            return 101;
        }
        if (tiRoleMapper.selectCountRoleMenuByMenuId(menuId) > 0) {
            return 102;
        }
        TiMenu tiMenu = new TiMenu();
        tiMenu.setMenuId(menuId);
        tiMenu.setState(2);
        Integer updateById = tiMenuMapper.updateById(tiMenu);
        tiRoleMenuRefMapper.deleteById(menuId);
        return updateById;
    }

    /**
     * 通过菜单id
     * 查询上级菜单
     * 查询菜单权限
     *
     * @param menuId
     * @return
     */
    @Override
    public TiMenu queryMenuByMenuId(Long menuId) {
        if (menuId != null) {
            TiMenu queryMenuByMenuId = tiMenuMapper.queryMenuByMenuId(menuId);
            logger.info("queryMenuByMenuId={}", queryMenuByMenuId);
            if (queryMenuByMenuId != null) {
                return queryMenuByMenuId;
            }
        }
        return null;
    }
}
